package com.redis.springtest;

import com.redis.springtest.config.RedisConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.redis.connection.RedisListCommands;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author lzy
 * @create 2020-07-27 下午12:18
 */
public class AppRedisList {
    private static final String CHARSET = "utf-8";

    public static void main(String[] args) throws UnsupportedEncodingException {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(RedisConfig.class);
        final RedisTemplate redisTemplate = ctx.getBean(RedisTemplate.class);

        final ListOperations listOperations = redisTemplate.opsForList();

        // 删除链表,便于多次测试
        redisTemplate.delete("list");

        // 把node3插入到链表中
        listOperations.leftPush("list", "node3");

        List<String> nodeList = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            nodeList.add("node" + i);
        }
        // 相当于lpush把多个值从左插入到链表中
        listOperations.leftPushAll("list", nodeList);

        listOperations.rightPush("list", "node4");

        // 获取下标为0的节点
        final Object list0 = listOperations.index("list", 0);

        // 获取列表长度
        final Long count = listOperations.size("list");
        // 从左边弹出一个节点
        final Object lpop = listOperations.leftPop("list");
        // 从右边弹出一个节点
        final Object rpop = listOperations.rightPop("list");
        // 注意，需要使用
        redisTemplate.getConnectionFactory().getConnection().lInsert("list".getBytes(CHARSET), RedisListCommands.Position.AFTER, "node2".getBytes(CHARSET), "after-node".getBytes(CHARSET));
        // 判断list是否存在, 如果存在则从左边插入head节点
        listOperations.leftPushIfPresent("list", "head");
        // 判断list是否存在, 如果存在则从右边插入end节点
        listOperations.rightPushIfPresent("list", "end");
        // 从左到右, 下标从0到10的元素
        final List valueList = listOperations.range("list", 0, 10);

        nodeList.clear();
        for (int i = 1; i <= 3; i++) {
            nodeList.add("node");
        }

        // 在链表左边插入三个值为node的节点
        listOperations.leftPushAll("list", nodeList);
        // 从左边到右边至多删除3个节点
        listOperations.remove("list", 3, "node");
        // 给链表下标为0的节点设置新值
        listOperations.set("list", 0, "new_head_value");

        printList(redisTemplate, "list");
    }

    private static void printList(RedisTemplate redisTemplate, String key) {
        // 链表长度
        final Long size = redisTemplate.opsForList().size(key);
        // 获取整个链表的值
        final List valueList = redisTemplate.opsForList().range(key, 0, size);
        // 打印
        System.out.println(valueList);
    }
}
